#include "storage.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static bool write_record_append(const char *path, const void *record, size_t size) {
	FILE *fp = fopen(path, "ab");
	if (!fp) return false;
	size_t n = fwrite(record, 1, size, fp);
	fclose(fp);
	return n == size;
}

static bool read_all_records(const char *path, size_t record_size, void **out_buf, size_t *out_count) {
	*out_buf = NULL;
	*out_count = 0;
	FILE *fp = fopen(path, "rb");
	if (!fp) {
		return true; /* 不存在视为空 */
	}
	if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); return false; }
	long bytes = ftell(fp);
	if (bytes < 0) { fclose(fp); return false; }
	if (fseek(fp, 0, SEEK_SET) != 0) { fclose(fp); return false; }
	if (bytes == 0) { fclose(fp); return true; }
	size_t count = (size_t)bytes / record_size;
	void *buf = malloc(count * record_size);
	if (!buf) { fclose(fp); return false; }
	size_t n = fread(buf, record_size, count, fp);
	fclose(fp);
	if (n != count) { free(buf); return false; }
	*out_buf = buf;
	*out_count = count;
	return true;
}

static bool rewrite_all_records(const char *path, const void *array, size_t count, size_t record_size) {
	FILE *fp = fopen(path, "wb");
	if (!fp) return false;
	size_t n = fwrite(array, record_size, count, fp);
	fclose(fp);
	return n == count;
}

bool file_exists(const char *path) {
	FILE *fp = fopen(path, "rb");
	if (!fp) return false;
	fclose(fp);
	return true;
}

/* 课程操作 */
bool save_course_append(const Course *course) {
	return write_record_append(COURSE_FILE_PATH, course, sizeof(Course));
}

bool load_all_courses(Course **out_array, size_t *out_count) {
	void *buf = NULL; size_t count = 0;
	bool ok = read_all_records(COURSE_FILE_PATH, sizeof(Course), &buf, &count);
	if (!ok) return false;
	*out_array = (Course*)buf;
	*out_count = count;
	return true;
}

bool rewrite_all_courses(const Course *array, size_t count) {
	return rewrite_all_records(COURSE_FILE_PATH, array, count, sizeof(Course));
}

/* 选课操作 */
bool save_selection_append(const StudentSelection *sel) {
	return write_record_append(STUDENT_SELECTION_FILE_PATH, sel, sizeof(StudentSelection));
}

bool load_all_selections(StudentSelection **out_array, size_t *out_count) {
	void *buf = NULL; size_t count = 0;
	bool ok = read_all_records(STUDENT_SELECTION_FILE_PATH, sizeof(StudentSelection), &buf, &count);
	if (!ok) return false;
	*out_array = (StudentSelection*)buf;
	*out_count = count;
	return true;
}

bool rewrite_all_selections(const StudentSelection *array, size_t count) {
	return rewrite_all_records(STUDENT_SELECTION_FILE_PATH, array, count, sizeof(StudentSelection));
}


